package com.code.soulspring.template;

import java.util.ArrayList;
import java.util.List;

/**
 * spring的模板方法是如下这种，分两部分
 *      静：比如固定的 构造、依赖注入、初始化、销毁 等功能，都是固定的，对开发者不可见，即对修改关闭
 *      动：比如在依赖注入阶段我想扩展能力，增加对 @Resource 等注解的解析能力，此时这部分就是动，即对扩展开放
 *      模板方法：就是对 动，未来可变的地方设计抽象为一个接口，在合适的地方编写 接口回调 ；
 *  需要注意：
 *      这里 spring 的模板方法，是把 回调接口的所有实现类的回调方法都执行了一遍；
 *      就看自己的业务，也可以根据入参回调某一个，也可以像 spring 这样遍历所有实现进行回调
 * @author lyf
 * @date 2022-09-23 23:31
 */
public class TestMethodTemplatePattern {
    public static void main(String[] args) {
        MyBeanFactory beanFactory = new MyBeanFactory();
        beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
        beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
        beanFactory.getBean();
    }

    static class MyBeanFactory {
        public Object getBean() {
            Object bean = new Object();
            System.out.println("构造：" + bean);
            System.out.println("依赖注入：" + bean);
            for (BeanPostProcessor processor : processors) {
                processor.inject(bean);
            }
            System.out.println("初始化：" + bean);
            return bean;
        }

        private List<BeanPostProcessor> processors = new ArrayList<>();

        public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
            processors.add(beanPostProcessor);
        }
    }

    interface BeanPostProcessor {
        void inject(Object bean);
    }
}

